package com.yingxue.demo.exception;

import com.yingxue.demo.exception.enums.BadRequestExceptionEnum;
import com.yingxue.demo.exception.enums.ServerExceptionEnum;
import com.yingxue.demo.exception.enums.UnauthorizedExceptionEnum;
import com.yingxue.demo.util.ResultVOUtil;
import com.yingxue.demo.vo.resp.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Package: com.company.scaffold.exception.handler
 * @Author: Mr.Waves
 * @Date: 2020-03-09 10:43
 * @Description: 全局异常统一处理类
 **/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * @ExceptionHandler采取就近原则，会从类型最接近的Exception子类开始匹配
     * 500
     */
    @ExceptionHandler(value = Exception.class)
    public ResultVO exceptionHandler(Exception e) {
        log.error("【未知异常】: {} {}",e.getLocalizedMessage(),e);
        return ResultVOUtil.error(ServerExceptionEnum.UNKNOWN_EXCEPTION);
    }

    /**
     * Biz
     */
    @ExceptionHandler(value = BizException.class)
    public ResultVO exceptionHandler(BizException e) {
        log.error("【业务异常】: {} {}",e.getLocalizedMessage(),e);
        return ResultVOUtil.error(e.getExceptionEnum());
    }

    /**
     * SpringMVC Validate
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResultVO exceptionHandler(MethodArgumentNotValidException e) {
        List<String> errorMessages = e.getBindingResult().getAllErrors().stream().map(i -> i.getDefaultMessage()).collect(Collectors.toList());
        log.error("【参数异常】: {} {}",e.getLocalizedMessage(),e);
        return ResultVOUtil.error(BadRequestExceptionEnum.ARGS_INVALID,errorMessages.get(0));
    }

    /**
     * 401
     */
    @ExceptionHandler(value = UnauthorizedException.class)
    public ResultVO exceptionHandler(UnauthorizedException e) {
        log.error("【授权异常】: {} {}",e.getLocalizedMessage(),e);
        return ResultVOUtil.error(UnauthorizedExceptionEnum.PERMISSION_DENIED);
    }
}
